package com.frank.loadinglibrary.common.element;

import com.frank.loadinglibrary.base.baseanimations.BaseAnimationController;
import com.frank.loadinglibrary.base.baseelement.BaseElement;
import com.frank.loadinglibrary.base.baseelement.IComponentCallback;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;

import java.util.ArrayList;

public class ChrysantheElement extends BaseElement implements BaseAnimationController.IAnimationController<AnimatorValue> {

    //画笔
    private Paint mPaint;

    //组件回调接口
    private IComponentCallback callback;
    //可配置参数
    private ChrysantheParams params;

    //用于刷新的次数统计，每7次清零，用于做透明度变化
    private int reflushCount = 0;

    private ChrysantheElement(ChrysantheParams param, IComponentCallback cl) {
        super();
        this.params = param;
        this.callback = cl;
    }

    @Override
    public BaseAnimationController.IAnimationController<AnimatorValue> initAnimationController() {
        return this;
    }

    @Override
    public void initPaint() {
        super.initPaint();
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setStyle(Paint.Style.FILL_STYLE);
            mPaint.setStrokeWidth(params.mLineWidth);
            mPaint.setColor(Color.WHITE);
        }
    }

    @Override
    public ArrayList<AnimatorValue> onCreateAnimators() {
        ArrayList<AnimatorValue> animators = new ArrayList<>();
        AnimatorValue alphaAnim = new AnimatorValue();
        alphaAnim.setDuration(params.durtion);
        alphaAnim.setLoopedCount(-1);
        alphaAnim.setLoopedListener(animator -> {
            if (callback != null) {
                callback.reflushComponent();
            }
        });
        animators.add(alphaAnim);
        return animators;
    }

    @Override
    public void onAnimationReset() {
        //do nothing because donot need to reset animation params
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        float width = Math.min(getWidth(), getHeight());
        for (int i = 0; i < params.lineCount; i++) {
            int position = (i + reflushCount) % params.lineCount;
            mPaint.setAlpha(params.alphaFloats[position]);
            canvas.drawLine(getWidth() / 2 - width / 2 + params.mPadding, getHeight() / 2, getWidth() / 2 - width / 2 + params.mPadding + params.mLineLength, getHeight() / 2, mPaint);
            canvas.rotate(360f / params.lineCount, getWidth() / 2, getHeight() / 2);
        }
        reflushCount++;
        if (reflushCount >= params.lineCount - 1) {
            reflushCount = 0;
        }
    }

    /**
     * 构建者
     */
    public static class ChrysantheBuild {

        private ChrysantheElement.ChrysantheParams params;
        private IComponentCallback call;

        public ChrysantheBuild(IComponentCallback c) {
            call = c;
            params = new ChrysantheElement.ChrysantheParams();
            setLineCount(ChrysantheParams.DEFAULT_COUNT);
            setDurtion(ChrysantheParams.BASE_DURTION_TIME);
        }

        public ChrysantheElement.ChrysantheBuild setLineCount(int count) {
            params.lineCount = count;
            params.alphaFloats = new float[params.lineCount];
            params.mAlphaSpace = 0.8f / (params.lineCount - 1);
            for (int i = 0; i < params.lineCount; i++) {
                params.alphaFloats[i] = (float) (0.1 + i * params.mAlphaSpace);
            }
            return this;
        }

        public ChrysantheElement.ChrysantheBuild setLineWidth(float lineWidth) {
            params.mLineWidth = lineWidth;
            return this;
        }

        public ChrysantheElement.ChrysantheBuild setLineLength(float lineLength) {
            params.mLineLength = lineLength;
            return this;
        }

        public ChrysantheElement.ChrysantheBuild setDurtion(int dur) {
            params.durtion = dur;
            return this;
        }

        public ChrysantheElement.ChrysantheBuild setLeftAndRightPadding(float pad) {
            params.mPadding = pad;
            return this;
        }

        public ChrysantheElement build() {
            return new ChrysantheElement(params, call);
        }
    }

    /***
     * 可配置参数类
     */
    public static class ChrysantheParams {
        //默认时长基数
        private static final int BASE_DURTION_TIME = 200;
        //设置默认的最大个数
        private static final int DEFAULT_COUNT = 12;
        //左右边距
        private static final float DEFAULT_MAGIN_HOR = 10f;
        //绘制线长
        private float mLineLength = 70;
        //绘制线的宽度
        private float mLineWidth = 15;
        //透明度数组
        public float[] alphaFloats;
        //线条数
        private int lineCount = DEFAULT_COUNT;
        private float mAlphaSpace = 0f;
        private int durtion = BASE_DURTION_TIME;
        private float mPadding = DEFAULT_MAGIN_HOR;
    }
}
